//----------------------------------Include-------------------------------------
#include <stdint.h>
#include "mcu.h"
//------------------------------------------------------------------------------

//电源管理（多个片上电源）
//  DCDC 电压转换器，提供 0.9∼1.3V 输出，为系统电源域的电路供电，可调节 DCDC 输出，以支持动态电压频率调整 DVFS，来优化运行时的功耗
//  LDOPMC，典型值 1.1V 输出的线性稳压器，为电源管理域的电路供电
//  LDOOTP，典型值 2.5V 输出的线性稳压器，为 OTP 供电，仅可在烧写 OTP 时打开
//（系统电源域专指由 VDD_SOC 供电的逻辑和存储电路）
//（电源管理域专指由 VPMC 供电的逻辑和存储电路）

//内置 2 个 PLL 用以生成系统所需要的各种频率的时钟，其中 PLL0 有 3 路，PLL1 有 4 路独立分频的时钟输出，所以 PLL 时钟源共有 7 个
//PLL 默认使用 XTAL24M 时钟作为参考时钟，各 PLL 已预先设置了默认工作频率
//选择值  时钟源     默认频率   说明
//0      CLK_24M    24MHz     24MHz 时钟源
//1      PLL0CLK0   720MHz    默认作为处理器的时钟源
//2      PLL0CLK1   600MHz
//3      PLL0CLK2   400MHz
//4      PLL1CLK0   800MHz
//5      PLL1CLK1   666MHz
//6      PLL1CLK2   500MHz
//7      PLL1CLK3   266MHz
//每个功能时钟从上面8选1，并且可单独设置分频系数进行分频，分频系数范围为从 1 到 256 的任意整数
//为便于使用，各功能时钟已预先设置了时钟源选择和分频系数
//功能时钟名称       默认时钟源    默认分频系数    默认频率   应用
//CLK_TOP_HART0     PLL0CLK0         2          360MHz    CPU0 核心/ILM0/DLM0/FGPIO0
//CLK_TOP_MCHTMR0   CLK24M           1           24MHz    MCHTMR0 计时
//CLK_TOP_AHB       CLK_TOP_HART0    2          180MHz    外设总线/HDMA/AHB SRAM/电机系统/ACMP/GPIO
//CLK_TOP_CAN0~3    PLL1CLK0        10           80MHz    CAN0~3 接口
//CLK_TOP_GPTMR0~3  PLL1CLK0         8          100MHz    GPTMR0~3 计时
//CLK_TOP_I2C0~3    PLL1CLK0        10           80MHz    I2C0~3 接口
//CLK_TOP_SPI0~3    PLL1CLK0        10           80MHz    SPI0~3 接口
//CLK_TOP_UART0~7   PLL1CLK0        10           80MHz    UART0~7 接口
//CLK_TOP_XPI0      PLL1CLK1         2          333MHz    XPI0 接口（实际频率与启动配置有关）
//CLK_TOP_ANA0~3    PLL1CLK0         4          200MHz    ADC0/ADC1/DAC0/DAC1 备选时钟
//CLK_TOP_REF0~1    PLL1CLK2        10           50MHz    REF0~1 备选时钟
//CLK_TOP_ADC0~1    CLK_TOP_AHB                 180MHz    ADC0~1
//CLK_TOP_DAC0~1    CLK_TOP_AHB                 180MHz    DAC0~1

//还有一部分模块没有使用功能时钟而是直接连接时钟源，包括电源管理域的全部模块，还包括系统电源域的部分计时模块
//电源管理域模块
//模块     时钟源
//PDGO    CLK_32K
//PTMR    CLK_24M
//PWDG    CLK_24M 和 CLK_32K
//PUART   CLK_24M
//PGPIO   CLK_24M
//系统电源域模块
//模块           时钟源
//WDG0∼WDG1     CLK_32K 和 CLK_TOP_AHB
//USB0          CLK_24M

//------------------------------------Type--------------------------------------
typedef struct{
  uint32_t  cpuclk;
}t_clk;
//------------------------------------------------------------------------------

//-----------------------------------Macro--------------------------------------
//内部时钟
#define RC32K                   (32000)     //直接为电源管理域的 PDGO 模块提供时钟
#define RC24M                (24000000)
//外部时钟
#define XTAL24M              (24000000)     //XTAL24M 默认自动使能
//------------------------------------------------------------------------------

//--------------------------------Static Var------------------------------------
//static t_clk                 nt_clk;
//------------------------------------------------------------------------------

//--------------------------------Public Func-----------------------------------
void mcu_sys_clock(void)
{
  uint32_t cpu0_freq = clock_get_frequency(clock_cpu0);

  if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) {
    pllctlv2_xtal_set_rampup_time(HPM_PLLCTLV2, 32UL * 1000UL * 9U);    /* Configure the External OSC ramp-up time: ~9ms */
    sysctl_clock_set_preset(HPM_SYSCTL, 2);                             /* Select clock setting preset1 */
  }

  /* group0[0] */
  clock_add_to_group(clock_cpu0,    0);
  clock_add_to_group(clock_ahb,     0);
  clock_add_to_group(clock_lmm0,    0);
  clock_add_to_group(clock_mchtmr0, 0);
  clock_add_to_group(clock_rom,     0);
  clock_add_to_group(clock_gptmr0,  0);
  clock_add_to_group(clock_gptmr1,  0);
  clock_add_to_group(clock_i2c2,    0);
  clock_add_to_group(clock_spi1,    0);
  clock_add_to_group(clock_uart0,   0);
  clock_add_to_group(clock_uart3,   0);

  clock_add_to_group(clock_watchdog0, 0);
  clock_add_to_group(clock_watchdog1, 0);
  clock_add_to_group(clock_mbx0,      0);
  clock_add_to_group(clock_tsns,      0);
  clock_add_to_group(clock_crc0,      0);
  clock_add_to_group(clock_adc0,      0);
  clock_add_to_group(clock_acmp,      0);
  clock_add_to_group(clock_kman,      0);
  clock_add_to_group(clock_gpio,      0);
  clock_add_to_group(clock_hdma,      0);
  clock_add_to_group(clock_xpi0,      0);
  clock_add_to_group(clock_usb0,      0);

  /* Connect Group0 to CPU0 */
  clock_connect_group_to_cpu(0, 0);

  /* Bump up DCDC voltage to 1175mv */
  pcfg_dcdc_set_voltage(HPM_PCFG, 1175);

  /* Configure CPU to 360MHz, AXI/AHB to 120MHz */
  sysctl_config_cpu0_domain_clock(HPM_SYSCTL, clock_source_pll0_clk0, 2, 3);

  /* Configure PLL0 Post Divider */
  pllctlv2_set_postdiv(HPM_PLLCTLV2, 0, 0, 0);    /* PLL0CLK0: 720MHz */
  pllctlv2_set_postdiv(HPM_PLLCTLV2, 0, 1, 3);    /* PLL0CLK1: 450MHz */
  pllctlv2_set_postdiv(HPM_PLLCTLV2, 0, 2, 7);    /* PLL0CLK2: 300MHz */

  /* Configure PLL0 Frequency to 720MHz */
  pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, 0, 720000000);

  clock_update_core_clock();

  /* Configure mchtmr to 24MHz */
  clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1);
}
//------------------------------------EOF---------------------------------------


